{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# reference tensorflow/image retraining\n",
    "from __future__ import absolute_import\n",
    "from __future__ import division\n",
    "from __future__ import print_function\n",
    "\n",
    "import argparse\n",
    "from datetime import datetime\n",
    "import hashlib\n",
    "import os.path\n",
    "import random\n",
    "import re\n",
    "import struct\n",
    "import sys\n",
    "import tarfile\n",
    "\n",
    "import numpy as np\n",
    "from six.moves import urllib\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow.python.framework import graph_util\n",
    "from tensorflow.python.framework import tensor_shape\n",
    "from tensorflow.python.platform import gfile\n",
    "from tensorflow.python.util import compat\n",
    "\n",
    "FLAGS = None\n",
    "\n",
    "# Downloads the inception weights \n",
    "DATA_URL = 'http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'\n",
    "\n",
    "BOTTLENECK_TENSOR_NAME = 'pool_3/_reshape:0'\n",
    "BOTTLENECK_TENSOR_SIZE = 2048\n",
    "MODEL_INPUT_WIDTH = 299\n",
    "MODEL_INPUT_HEIGHT = 299\n",
    "MODEL_INPUT_DEPTH = 3\n",
    "JPEG_DATA_TENSOR_NAME = 'DecodeJpeg/contents:0'\n",
    "RESIZED_INPUT_TENSOR_NAME = 'ResizeBilinear:0'\n",
    "MAX_NUM_IMAGES_PER_CLASS = 2 ** 27 - 1  # ~134M\n",
    "\n",
    "\n",
    "def create_image_lists(image_dir, testing_percentage, validation_percentage):\n",
    "#check for the image directory\n",
    "  if not gfile.Exists(image_dir):\n",
    "    print(\"Image directory '\" + image_dir + \"' not found.\")\n",
    "    return None\n",
    "  result = {}\n",
    "  sub_dirs = [x[0] for x in gfile.Walk(image_dir)]\n",
    "  # The root directory comes first, so skip it.\n",
    "  is_root_dir = True\n",
    "  for sub_dir in sub_dirs:\n",
    "    if is_root_dir:\n",
    "      is_root_dir = False\n",
    "      continue\n",
    "    extensions = ['jpg', 'jpeg', 'JPG', 'JPEG']\n",
    "    file_list = []\n",
    "    dir_name = os.path.basename(sub_dir)\n",
    "    if dir_name == image_dir:\n",
    "      continue\n",
    "    print(\"Looking for images in '\" + dir_name + \"'\")\n",
    "    for extension in extensions:\n",
    "      file_glob = os.path.join(image_dir, dir_name, '*.' + extension)\n",
    "      file_list.extend(gfile.Glob(file_glob))\n",
    "    if not file_list:\n",
    "      print('No files found')\n",
    "      continue\n",
    "    if len(file_list) < 20:\n",
    "      print('WARNING: Folder has less than 20 images, which may cause issues.')\n",
    "    elif len(file_list) > MAX_NUM_IMAGES_PER_CLASS:\n",
    "      print('WARNING: Folder {} has more than {} images. Some images will '\n",
    "            'never be selected.'.format(dir_name, MAX_NUM_IMAGES_PER_CLASS))\n",
    "    label_name = re.sub(r'[^a-z0-9]+', ' ', dir_name.lower())\n",
    "    training_images = []\n",
    "    testing_images = []\n",
    "    validation_images = []\n",
    "    for file_name in file_list:\n",
    "      base_name = os.path.basename(file_name)\n",
    "      hash_name = re.sub(r'_nohash_.*$', '', file_name)\n",
    "      hash_name_hashed = hashlib.sha1(compat.as_bytes(hash_name)).hexdigest()\n",
    "      percentage_hash = ((int(hash_name_hashed, 16) %\n",
    "                          (MAX_NUM_IMAGES_PER_CLASS + 1)) *\n",
    "                         (100.0 / MAX_NUM_IMAGES_PER_CLASS))\n",
    "      if percentage_hash < validation_percentage:\n",
    "        validation_images.append(base_name)\n",
    "      elif percentage_hash < (testing_percentage + validation_percentage):\n",
    "        testing_images.append(base_name)\n",
    "      else:\n",
    "        training_images.append(base_name)\n",
    "    result[label_name] = {\n",
    "        'dir': dir_name,\n",
    "        'training': training_images,\n",
    "        'testing': testing_images,\n",
    "        'validation': validation_images,\n",
    "    }\n",
    "  return result\n",
    "\n",
    "\n",
    "def get_image_path(image_lists, label_name, index, image_dir, category):\n",
    "  if label_name not in image_lists:\n",
    "    tf.logging.fatal('Label does not exist %s.', label_name)\n",
    "  label_lists = image_lists[label_name]\n",
    "  if category not in label_lists:\n",
    "    tf.logging.fatal('Category does not exist %s.', category)\n",
    "  category_list = label_lists[category]\n",
    "  if not category_list:\n",
    "    tf.logging.fatal('Label %s has no images in the category %s.',\n",
    "                     label_name, category)\n",
    "  mod_index = index % len(category_list)\n",
    "  base_name = category_list[mod_index]\n",
    "  sub_dir = label_lists['dir']\n",
    "  full_path = os.path.join(image_dir, sub_dir, base_name)\n",
    "  return full_path\n",
    "\n",
    "\n",
    "#For bottle necks , better not to store these , takes a lot of memory\n",
    "def get_bottleneck_path(image_lists, label_name, index, bottleneck_dir,\n",
    "                        category):\n",
    "  return get_image_path(image_lists, label_name, index, bottleneck_dir,\n",
    "                        category) + '.txt'\n",
    "\n",
    "#Store the graph (imp)\n",
    "def create_inception_graph():\n",
    "  with tf.Graph().as_default() as graph:\n",
    "    model_filename = os.path.join(\n",
    "        FLAGS.model_dir, 'classify_image_graph_def.pb')\n",
    "    with gfile.FastGFile(model_filename, 'rb') as f:\n",
    "      graph_def = tf.GraphDef()\n",
    "      graph_def.ParseFromString(f.read())\n",
    "      bottleneck_tensor, jpeg_data_tensor, resized_input_tensor = (\n",
    "          tf.import_graph_def(graph_def, name='', return_elements=[\n",
    "              BOTTLENECK_TENSOR_NAME, JPEG_DATA_TENSOR_NAME,\n",
    "              RESIZED_INPUT_TENSOR_NAME]))\n",
    "  return graph, bottleneck_tensor, jpeg_data_tensor, resized_input_tensor\n",
    "\n",
    "\n",
    "def run_bottleneck_on_image(sess, image_data, image_data_tensor,\n",
    "                            bottleneck_tensor):\n",
    "  bottleneck_values = sess.run(\n",
    "      bottleneck_tensor,\n",
    "      {image_data_tensor: image_data})\n",
    "  bottleneck_values = np.squeeze(bottleneck_values)\n",
    "  return bottleneck_values\n",
    "\n",
    "\n",
    "def maybe_download_and_extract():\n",
    "  \"\"\"Download and extract model tar file.\n",
    "\n",
    "  If the pretrained model we're using doesn't already exist, this function\n",
    "  downloads it from the TensorFlow.org website and unpacks it into a directory.\n",
    "  \"\"\"\n",
    "  dest_directory = FLAGS.model_dir\n",
    "  if not os.path.exists(dest_directory):\n",
    "    os.makedirs(dest_directory)\n",
    "  filename = DATA_URL.split('/')[-1]\n",
    "  filepath = os.path.join(dest_directory, filename)\n",
    "  if not os.path.exists(filepath):\n",
    "\n",
    "    def _progress(count, block_size, total_size):\n",
    "      sys.stdout.write('\\r>> Downloading %s %.1f%%' %\n",
    "                       (filename,\n",
    "                        float(count * block_size) / float(total_size) * 100.0))\n",
    "      sys.stdout.flush()\n",
    "\n",
    "    filepath, _ = urllib.request.urlretrieve(DATA_URL,\n",
    "                                             filepath,\n",
    "                                             _progress)\n",
    "    print()\n",
    "    statinfo = os.stat(filepath)\n",
    "    print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')\n",
    "  tarfile.open(filepath, 'r:gz').extractall(dest_directory)\n",
    "\n",
    "\n",
    "def ensure_dir_exists(dir_name):\n",
    "  \"\"\"Makes sure the folder exists on disk.\n",
    "\n",
    "  Args:\n",
    "    dir_name: Path string to the folder we want to create.\n",
    "  \"\"\"\n",
    "  if not os.path.exists(dir_name):\n",
    "    os.makedirs(dir_name)\n",
    "\n",
    "\n",
    "def write_list_of_floats_to_file(list_of_floats, file_path):\n",
    "  \"\"\"Writes a given list of floats to a binary file.\n",
    "\n",
    "  Args:\n",
    "    list_of_floats: List of floats we want to write to a file.\n",
    "    file_path: Path to a file where list of floats will be stored.\n",
    "\n",
    "  \"\"\"\n",
    "\n",
    "  s = struct.pack('d' * BOTTLENECK_TENSOR_SIZE, *list_of_floats)\n",
    "  with open(file_path, 'wb') as f:\n",
    "    f.write(s)\n",
    "\n",
    "\n",
    "def read_list_of_floats_from_file(file_path):\n",
    "  \"\"\"Reads list of floats from a given file.\n",
    "\n",
    "  Args:\n",
    "    file_path: Path to a file where list of floats was stored.\n",
    "  Returns:\n",
    "    Array of bottleneck values (list of floats).\n",
    "\n",
    "  \"\"\"\n",
    "\n",
    "  with open(file_path, 'rb') as f:\n",
    "    s = struct.unpack('d' * BOTTLENECK_TENSOR_SIZE, f.read())\n",
    "    return list(s)\n",
    "\n",
    "\n",
    "bottleneck_path_2_bottleneck_values = {}\n",
    "\n",
    "\n",
    "def create_bottleneck_file(bottleneck_path, image_lists, label_name, index,\n",
    "                           image_dir, category, sess, jpeg_data_tensor,\n",
    "                           bottleneck_tensor):\n",
    "  \"\"\"Create a single bottleneck file.\"\"\"\n",
    "  print('Creating bottleneck at ' + bottleneck_path)\n",
    "  image_path = get_image_path(image_lists, label_name, index,\n",
    "                              image_dir, category)\n",
    "  if not gfile.Exists(image_path):\n",
    "    tf.logging.fatal('File does not exist %s', image_path)\n",
    "  image_data = gfile.FastGFile(image_path, 'rb').read()\n",
    "  bottleneck_values = run_bottleneck_on_image(sess, image_data,\n",
    "                                              jpeg_data_tensor,\n",
    "                                              bottleneck_tensor)\n",
    "  bottleneck_string = ','.join(str(x) for x in bottleneck_values)\n",
    "  with open(bottleneck_path, 'w') as bottleneck_file:\n",
    "    bottleneck_file.write(bottleneck_string)\n",
    "\n",
    "\n",
    "def get_or_create_bottleneck(sess, image_lists, label_name, index, image_dir,\n",
    "                             category, bottleneck_dir, jpeg_data_tensor,\n",
    "                             bottleneck_tensor):\n",
    "  label_lists = image_lists[label_name]\n",
    "  sub_dir = label_lists['dir']\n",
    "  sub_dir_path = os.path.join(bottleneck_dir, sub_dir)\n",
    "  ensure_dir_exists(sub_dir_path)\n",
    "  bottleneck_path = get_bottleneck_path(image_lists, label_name, index,\n",
    "                                        bottleneck_dir, category)\n",
    "  if not os.path.exists(bottleneck_path):\n",
    "    create_bottleneck_file(bottleneck_path, image_lists, label_name, index,\n",
    "                           image_dir, category, sess, jpeg_data_tensor,\n",
    "                           bottleneck_tensor)\n",
    "  with open(bottleneck_path, 'r') as bottleneck_file:\n",
    "    bottleneck_string = bottleneck_file.read()\n",
    "  did_hit_error = False\n",
    "  try:\n",
    "    bottleneck_values = [float(x) for x in bottleneck_string.split(',')]\n",
    "  except ValueError:\n",
    "    print('Invalid float found, recreating bottleneck')\n",
    "    did_hit_error = True\n",
    "  if did_hit_error:\n",
    "    create_bottleneck_file(bottleneck_path, image_lists, label_name, index,\n",
    "                           image_dir, category, sess, jpeg_data_tensor,\n",
    "                           bottleneck_tensor)\n",
    "    with open(bottleneck_path, 'r') as bottleneck_file:\n",
    "      bottleneck_string = bottleneck_file.read()\n",
    "    # Allow exceptions to propagate here, since they shouldn't happen after a\n",
    "    # fresh creation\n",
    "    bottleneck_values = [float(x) for x in bottleneck_string.split(',')]\n",
    "  return bottleneck_values\n",
    "\n",
    "\n",
    "def cache_bottlenecks(sess, image_lists, image_dir, bottleneck_dir,\n",
    "                      jpeg_data_tensor, bottleneck_tensor):\n",
    "  how_many_bottlenecks = 0\n",
    "  ensure_dir_exists(bottleneck_dir)\n",
    "  for label_name, label_lists in image_lists.items():\n",
    "    for category in ['training', 'testing', 'validation']:\n",
    "      category_list = label_lists[category]\n",
    "      for index, unused_base_name in enumerate(category_list):\n",
    "        get_or_create_bottleneck(sess, image_lists, label_name, index,\n",
    "                                 image_dir, category, bottleneck_dir,\n",
    "                                 jpeg_data_tensor, bottleneck_tensor)\n",
    "\n",
    "        how_many_bottlenecks += 1\n",
    "        if how_many_bottlenecks % 100 == 0:\n",
    "          print(str(how_many_bottlenecks) + ' bottleneck files created.')\n",
    "\n",
    "\n",
    "def get_random_cached_bottlenecks(sess, image_lists, how_many, category,\n",
    "                                  bottleneck_dir, image_dir, jpeg_data_tensor,\n",
    "                                  bottleneck_tensor):\n",
    "\n",
    "\n",
    "  class_count = len(image_lists.keys())\n",
    "  bottlenecks = []\n",
    "  ground_truths = []\n",
    "  filenames = []\n",
    "  if how_many >= 0:\n",
    "    # Retrieve a random sample of bottlenecks.\n",
    "    for unused_i in range(how_many):\n",
    "      label_index = random.randrange(class_count)\n",
    "      label_name = list(image_lists.keys())[label_index]\n",
    "      image_index = random.randrange(MAX_NUM_IMAGES_PER_CLASS + 1)\n",
    "      image_name = get_image_path(image_lists, label_name, image_index,\n",
    "                                  image_dir, category)\n",
    "      bottleneck = get_or_create_bottleneck(sess, image_lists, label_name,\n",
    "                                            image_index, image_dir, category,\n",
    "                                            bottleneck_dir, jpeg_data_tensor,\n",
    "                                            bottleneck_tensor)\n",
    "      ground_truth = np.zeros(class_count, dtype=np.float32)\n",
    "      ground_truth[label_index] = 1.0\n",
    "      bottlenecks.append(bottleneck)\n",
    "      ground_truths.append(ground_truth)\n",
    "      filenames.append(image_name)\n",
    "  else:\n",
    "    # Retrieve all bottlenecks.\n",
    "    for label_index, label_name in enumerate(image_lists.keys()):\n",
    "      for image_index, image_name in enumerate(\n",
    "          image_lists[label_name][category]):\n",
    "        image_name = get_image_path(image_lists, label_name, image_index,\n",
    "                                    image_dir, category)\n",
    "        bottleneck = get_or_create_bottleneck(sess, image_lists, label_name,\n",
    "                                              image_index, image_dir, category,\n",
    "                                              bottleneck_dir, jpeg_data_tensor,\n",
    "                                              bottleneck_tensor)\n",
    "        ground_truth = np.zeros(class_count, dtype=np.float32)\n",
    "        ground_truth[label_index] = 1.0\n",
    "        bottlenecks.append(bottleneck)\n",
    "        ground_truths.append(ground_truth)\n",
    "        filenames.append(image_name)\n",
    "  return bottlenecks, ground_truths, filenames\n",
    "\n",
    "\n",
    "def get_random_distorted_bottlenecks(\n",
    "    sess, image_lists, how_many, category, image_dir, input_jpeg_tensor,\n",
    "    distorted_image, resized_input_tensor, bottleneck_tensor):\n",
    "  class_count = len(image_lists.keys())\n",
    "  bottlenecks = []\n",
    "  ground_truths = []\n",
    "  for unused_i in range(how_many):\n",
    "    label_index = random.randrange(class_count)\n",
    "    label_name = list(image_lists.keys())[label_index]\n",
    "    image_index = random.randrange(MAX_NUM_IMAGES_PER_CLASS + 1)\n",
    "    image_path = get_image_path(image_lists, label_name, image_index, image_dir,\n",
    "                                category)\n",
    "    if not gfile.Exists(image_path):\n",
    "      tf.logging.fatal('File does not exist %s', image_path)\n",
    "    jpeg_data = gfile.FastGFile(image_path, 'rb').read()\n",
    "    # Note that we materialize the distorted_image_data as a numpy array before\n",
    "    # sending running inference on the image. This involves 2 memory copies and\n",
    "    # might be optimized in other implementations.\n",
    "    distorted_image_data = sess.run(distorted_image,\n",
    "                                    {input_jpeg_tensor: jpeg_data})\n",
    "    bottleneck = run_bottleneck_on_image(sess, distorted_image_data,\n",
    "                                         resized_input_tensor,\n",
    "                                         bottleneck_tensor)\n",
    "    ground_truth = np.zeros(class_count, dtype=np.float32)\n",
    "    ground_truth[label_index] = 1.0\n",
    "    bottlenecks.append(bottleneck)\n",
    "    ground_truths.append(ground_truth)\n",
    "  return bottlenecks, ground_truths\n",
    "\n",
    "\n",
    "def should_distort_images(flip_left_right, random_crop, random_scale,\n",
    "                          random_brightness):\n",
    "  return (flip_left_right or (random_crop != 0) or (random_scale != 0) or\n",
    "          (random_brightness != 0))\n",
    "\n",
    "\n",
    "def add_input_distortions(flip_left_right, random_crop, random_scale,\n",
    "                          random_brightness):\n",
    "\n",
    "#  Cropping and Scaling are done so that it forms new images and even with distortion model can recognize it\n",
    "\n",
    "\n",
    "  jpeg_data = tf.placeholder(tf.string, name='DistortJPGInput')\n",
    "  decoded_image = tf.image.decode_jpeg(jpeg_data, channels=MODEL_INPUT_DEPTH)\n",
    "  decoded_image_as_float = tf.cast(decoded_image, dtype=tf.float32)\n",
    "  decoded_image_4d = tf.expand_dims(decoded_image_as_float, 0)\n",
    "  margin_scale = 1.0 + (random_crop / 100.0)\n",
    "  resize_scale = 1.0 + (random_scale / 100.0)\n",
    "  margin_scale_value = tf.constant(margin_scale)\n",
    "  resize_scale_value = tf.random_uniform(tensor_shape.scalar(),\n",
    "                                         minval=1.0,\n",
    "                                         maxval=resize_scale)\n",
    "  scale_value = tf.multiply(margin_scale_value, resize_scale_value)\n",
    "  precrop_width = tf.multiply(scale_value, MODEL_INPUT_WIDTH)\n",
    "  precrop_height = tf.multiply(scale_value, MODEL_INPUT_HEIGHT)\n",
    "  precrop_shape = tf.stack([precrop_height, precrop_width])\n",
    "  precrop_shape_as_int = tf.cast(precrop_shape, dtype=tf.int32)\n",
    "  precropped_image = tf.image.resize_bilinear(decoded_image_4d,\n",
    "                                              precrop_shape_as_int)\n",
    "  precropped_image_3d = tf.squeeze(precropped_image, squeeze_dims=[0])\n",
    "  cropped_image = tf.random_crop(precropped_image_3d,\n",
    "                                 [MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH,\n",
    "                                  MODEL_INPUT_DEPTH])\n",
    "  if flip_left_right:\n",
    "    flipped_image = tf.image.random_flip_left_right(cropped_image)\n",
    "  else:\n",
    "    flipped_image = cropped_image\n",
    "  brightness_min = 1.0 - (random_brightness / 100.0)\n",
    "  brightness_max = 1.0 + (random_brightness / 100.0)\n",
    "  brightness_value = tf.random_uniform(tensor_shape.scalar(),\n",
    "                                       minval=brightness_min,\n",
    "                                       maxval=brightness_max)\n",
    "  brightened_image = tf.multiply(flipped_image, brightness_value)\n",
    "  distort_result = tf.expand_dims(brightened_image, 0, name='DistortResult')\n",
    "  return jpeg_data, distort_result\n",
    "\n",
    "\n",
    "def variable_summaries(var):\n",
    "# tensorboard visulization\n",
    "  with tf.name_scope('summaries'):\n",
    "    mean = tf.reduce_mean(var)\n",
    "    tf.summary.scalar('mean', mean)\n",
    "    with tf.name_scope('stddev'):\n",
    "      stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))\n",
    "    tf.summary.scalar('stddev', stddev)\n",
    "    tf.summary.scalar('max', tf.reduce_max(var))\n",
    "    tf.summary.scalar('min', tf.reduce_min(var))\n",
    "    tf.summary.histogram('histogram', var)\n",
    "\n",
    "\n",
    "def add_final_training_ops(class_count, final_tensor_name, bottleneck_tensor):\n",
    "  with tf.name_scope('input'):\n",
    "    bottleneck_input = tf.placeholder_with_default(\n",
    "        bottleneck_tensor, shape=[None, BOTTLENECK_TENSOR_SIZE],\n",
    "        name='BottleneckInputPlaceholder')\n",
    "\n",
    "    ground_truth_input = tf.placeholder(tf.float32,\n",
    "                                        [None, class_count],\n",
    "                                        name='GroundTruthInput')\n",
    "\n",
    "  # Organizing the following ops as `final_training_ops` so they're easier\n",
    "  # to see in TensorBoard\n",
    "  layer_name = 'final_training_ops'\n",
    "  with tf.name_scope(layer_name):\n",
    "    with tf.name_scope('weights'):\n",
    "      initial_value = tf.truncated_normal([BOTTLENECK_TENSOR_SIZE, class_count],\n",
    "                                          stddev=0.001)\n",
    "\n",
    "      layer_weights = tf.Variable(initial_value, name='final_weights')\n",
    "\n",
    "      variable_summaries(layer_weights)\n",
    "    with tf.name_scope('biases'):\n",
    "      layer_biases = tf.Variable(tf.zeros([class_count]), name='final_biases')\n",
    "      variable_summaries(layer_biases)\n",
    "    with tf.name_scope('Wx_plus_b'):\n",
    "      logits = tf.matmul(bottleneck_input, layer_weights) + layer_biases\n",
    "      tf.summary.histogram('pre_activations', logits)\n",
    "\n",
    "  final_tensor = tf.nn.softmax(logits, name=final_tensor_name)\n",
    "  tf.summary.histogram('activations', final_tensor)\n",
    "\n",
    "  with tf.name_scope('cross_entropy'):\n",
    "    cross_entropy = tf.nn.softmax_cross_entropy_with_logits(\n",
    "        labels=ground_truth_input, logits=logits)\n",
    "    with tf.name_scope('total'):\n",
    "      cross_entropy_mean = tf.reduce_mean(cross_entropy)\n",
    "  tf.summary.scalar('cross_entropy', cross_entropy_mean)\n",
    "\n",
    "  with tf.name_scope('train'):\n",
    "    optimizer = tf.train.GradientDescentOptimizer(FLAGS.learning_rate)\n",
    "    train_step = optimizer.minimize(cross_entropy_mean)\n",
    "\n",
    "  return (train_step, cross_entropy_mean, bottleneck_input, ground_truth_input,\n",
    "          final_tensor)\n",
    "\n",
    "\n",
    "def add_evaluation_step(result_tensor, ground_truth_tensor):\n",
    "  with tf.name_scope('accuracy'):\n",
    "    with tf.name_scope('correct_prediction'):\n",
    "      prediction = tf.argmax(result_tensor, 1)\n",
    "      correct_prediction = tf.equal(\n",
    "          prediction, tf.argmax(ground_truth_tensor, 1))\n",
    "    with tf.name_scope('accuracy'):\n",
    "      evaluation_step = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
    "  tf.summary.scalar('accuracy', evaluation_step)\n",
    "  return evaluation_step, prediction\n",
    "\n",
    "\n",
    "def main(_):\n",
    "  # Setup the directory we'll write summaries to for TensorBoard\n",
    "  if tf.gfile.Exists(FLAGS.summaries_dir):\n",
    "    tf.gfile.DeleteRecursively(FLAGS.summaries_dir)\n",
    "  tf.gfile.MakeDirs(FLAGS.summaries_dir)\n",
    "\n",
    "  # Set up the pre-trained graph.\n",
    "  maybe_download_and_extract()\n",
    "  graph, bottleneck_tensor, jpeg_data_tensor, resized_image_tensor = (\n",
    "      create_inception_graph())\n",
    "\n",
    "  # Look at the folder structure, and create lists of all the images.\n",
    "  image_lists = create_image_lists(FLAGS.image_dir, FLAGS.testing_percentage,\n",
    "                                   FLAGS.validation_percentage)\n",
    "  class_count = len(image_lists.keys())\n",
    "  if class_count == 0:\n",
    "    print('No valid folders of images found at ' + FLAGS.image_dir)\n",
    "    return -1\n",
    "  if class_count == 1:\n",
    "    print('Only one valid folder of images found at ' + FLAGS.image_dir +\n",
    "          ' - multiple classes are needed for classification.')\n",
    "    return -1\n",
    "\n",
    "  # See if the command-line flags mean we're applying any distortions.\n",
    "  do_distort_images = should_distort_images(\n",
    "      FLAGS.flip_left_right, FLAGS.random_crop, FLAGS.random_scale,\n",
    "      FLAGS.random_brightness)\n",
    "\n",
    "  with tf.Session(graph=graph) as sess:\n",
    "\n",
    "    if do_distort_images:\n",
    "      # We will be applying distortions, so setup the operations we'll need.\n",
    "      (distorted_jpeg_data_tensor,\n",
    "       distorted_image_tensor) = add_input_distortions(\n",
    "           FLAGS.flip_left_right, FLAGS.random_crop,\n",
    "           FLAGS.random_scale, FLAGS.random_brightness)\n",
    "    else:\n",
    "      # We'll make sure we've calculated the 'bottleneck' image summaries and\n",
    "      cache_bottlenecks(sess, image_lists, FLAGS.image_dir,\n",
    "                        FLAGS.bottleneck_dir, jpeg_data_tensor,\n",
    "                        bottleneck_tensor)\n",
    "\n",
    "    # Add the new layer that we'll be training.\n",
    "    (train_step, cross_entropy, bottleneck_input, ground_truth_input,\n",
    "     final_tensor) = add_final_training_ops(len(image_lists.keys()),\n",
    "                                            FLAGS.final_tensor_name,\n",
    "                                            bottleneck_tensor)\n",
    "\n",
    "    # Create the operations we need to evaluate the accuracy of our new layer.\n",
    "    evaluation_step, prediction = add_evaluation_step(\n",
    "        final_tensor, ground_truth_input)\n",
    "\n",
    "    # Merge all the summaries and write them out to the summaries_dir\n",
    "    merged = tf.summary.merge_all()\n",
    "    train_writer = tf.summary.FileWriter(FLAGS.summaries_dir + '/train',\n",
    "                                         sess.graph)\n",
    "\n",
    "    validation_writer = tf.summary.FileWriter(\n",
    "        FLAGS.summaries_dir + '/validation')\n",
    "\n",
    "    # Set up all our weights to their initial default values.\n",
    "    init = tf.global_variables_initializer()\n",
    "    sess.run(init)\n",
    "\n",
    "    # Run the training for as many cycles as requested on the command line.\n",
    "    for i in range(FLAGS.how_many_training_steps):\n",
    "      # Get a batch of input bottleneck values, either calculated fresh every\n",
    "      # time with distortions applied, or from the cache stored on disk.\n",
    "      if do_distort_images:\n",
    "        (train_bottlenecks,\n",
    "         train_ground_truth) = get_random_distorted_bottlenecks(\n",
    "             sess, image_lists, FLAGS.train_batch_size, 'training',\n",
    "             FLAGS.image_dir, distorted_jpeg_data_tensor,\n",
    "             distorted_image_tensor, resized_image_tensor, bottleneck_tensor)\n",
    "      else:\n",
    "        (train_bottlenecks,\n",
    "         train_ground_truth, _) = get_random_cached_bottlenecks(\n",
    "             sess, image_lists, FLAGS.train_batch_size, 'training',\n",
    "             FLAGS.bottleneck_dir, FLAGS.image_dir, jpeg_data_tensor,\n",
    "             bottleneck_tensor)\n",
    "      # Feed the bottlenecks and ground truth into the graph, and run a training\n",
    "      # step. Capture training summaries for TensorBoard with the `merged` op.\n",
    "\n",
    "      train_summary, _ = sess.run(\n",
    "          [merged, train_step],\n",
    "          feed_dict={bottleneck_input: train_bottlenecks,\n",
    "                     ground_truth_input: train_ground_truth})\n",
    "      train_writer.add_summary(train_summary, i)\n",
    "\n",
    "      # Every so often, print out how well the graph is training.\n",
    "      is_last_step = (i + 1 == FLAGS.how_many_training_steps)\n",
    "      if (i % FLAGS.eval_step_interval) == 0 or is_last_step:\n",
    "        train_accuracy, cross_entropy_value = sess.run(\n",
    "            [evaluation_step, cross_entropy],\n",
    "            feed_dict={bottleneck_input: train_bottlenecks,\n",
    "                       ground_truth_input: train_ground_truth})\n",
    "        print('%s: Step %d: Train accuracy = %.1f%%' % (datetime.now(), i,\n",
    "                                                        train_accuracy * 100))\n",
    "        print('%s: Step %d: Cross entropy = %f' % (datetime.now(), i,\n",
    "                                                   cross_entropy_value))\n",
    "        validation_bottlenecks, validation_ground_truth, _ = (\n",
    "            get_random_cached_bottlenecks(\n",
    "                sess, image_lists, FLAGS.validation_batch_size, 'validation',\n",
    "                FLAGS.bottleneck_dir, FLAGS.image_dir, jpeg_data_tensor,\n",
    "                bottleneck_tensor))\n",
    "        # Run a validation step and capture training summaries for TensorBoard\n",
    "        # with the `merged` op.\n",
    "        validation_summary, validation_accuracy = sess.run(\n",
    "            [merged, evaluation_step],\n",
    "            feed_dict={bottleneck_input: validation_bottlenecks,\n",
    "                       ground_truth_input: validation_ground_truth})\n",
    "        validation_writer.add_summary(validation_summary, i)\n",
    "        print('%s: Step %d: Validation accuracy = %.1f%% (N=%d)' %\n",
    "              (datetime.now(), i, validation_accuracy * 100,\n",
    "               len(validation_bottlenecks)))\n",
    "\n",
    "    # We've completed all our training, so run a final test evaluation on\n",
    "    # some new images we haven't used before.\n",
    "    test_bottlenecks, test_ground_truth, test_filenames = (\n",
    "        get_random_cached_bottlenecks(sess, image_lists, FLAGS.test_batch_size,\n",
    "                                      'testing', FLAGS.bottleneck_dir,\n",
    "                                      FLAGS.image_dir, jpeg_data_tensor,\n",
    "                                      bottleneck_tensor))\n",
    "    test_accuracy, predictions = sess.run(\n",
    "        [evaluation_step, prediction],\n",
    "        feed_dict={bottleneck_input: test_bottlenecks,\n",
    "                   ground_truth_input: test_ground_truth})\n",
    "    print('Final test accuracy = %.1f%% (N=%d)' % (\n",
    "        test_accuracy * 100, len(test_bottlenecks)))\n",
    "\n",
    "    if FLAGS.print_misclassified_test_images:\n",
    "      print('=== MISCLASSIFIED TEST IMAGES ===')\n",
    "      for i, test_filename in enumerate(test_filenames):\n",
    "        if predictions[i] != test_ground_truth[i].argmax():\n",
    "          print('%70s  %s' % (test_filename,\n",
    "                              list(image_lists.keys())[predictions[i]]))\n",
    "\n",
    "    # Write out the trained graph and labels with the weights stored as\n",
    "    # constants.\n",
    "    output_graph_def = graph_util.convert_variables_to_constants(\n",
    "        sess, graph.as_graph_def(), [FLAGS.final_tensor_name])\n",
    "    with gfile.FastGFile(FLAGS.output_graph, 'wb') as f:\n",
    "      f.write(output_graph_def.SerializeToString())\n",
    "    with gfile.FastGFile(FLAGS.output_labels, 'w') as f:\n",
    "      f.write('\\n'.join(image_lists.keys()) + '\\n')\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "  parser = argparse.ArgumentParser()\n",
    "  parser.add_argument(\n",
    "      '--image_dir',\n",
    "      type=str,\n",
    "      default='',\n",
    "      help='Path to folders of labeled images.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--output_graph',\n",
    "      type=str,\n",
    "      default='/tmp/output_graph.pb',\n",
    "      # specify in arguments ~/name oftext folder\n",
    "      help='Where to save the trained graph.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--output_labels',\n",
    "      type=str,\n",
    "      default='/tmp/output_labels.txt',\n",
    "      # specify in arguments ~/name oftext folder\n",
    "      help='Where to save the trained graph\\'s labels.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--summaries_dir',\n",
    "      type=str,\n",
    "      default='/tmp/retrain_logs',\n",
    "      # specify in arguments ~/name oftext folder\n",
    "      help='Where to save summary logs for TensorBoard.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--how_many_training_steps',\n",
    "      type=int,\n",
    "      default=4000,\n",
    "      # specify in arguments ~/name oftext folder\n",
    "      help='How many training steps to run before ending.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--learning_rate',\n",
    "      type=float,\n",
    "      default=0.01,\n",
    "      # specify in arguments learning_rate = # but the default works fine, if u want to speed up teh trianing\n",
    "      help='How large a learning rate to use when training.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--testing_percentage',\n",
    "      type=int,\n",
    "      default=10,\n",
    "      help='What percentage of images to use as a test set.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--validation_percentage',\n",
    "      type=int,\n",
    "      default=10,\n",
    "      help='What percentage of images to use as a validation set.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--eval_step_interval',\n",
    "      type=int,\n",
    "      default=10,\n",
    "      help='How often to evaluate the training results.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--train_batch_size',\n",
    "      type=int,\n",
    "      default=100,\n",
    "      help='How many images to train on at a time.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--test_batch_size',\n",
    "      type=int,\n",
    "      default=-1,\n",
    "      help=\"\"\"\\\n",
    "      How many images to test on. This test set is only used once, to evaluate\n",
    "      the final accuracy of the model after training completes.\n",
    "      A value of -1 causes the entire test set to be used, which leads to more\n",
    "      stable results across runs.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--validation_batch_size',\n",
    "      type=int,\n",
    "      default=100,\n",
    "      help=\"\"\"\\\n",
    "      How many images to use in an evaluation batch. This validation set is\n",
    "      used much more often than the test set, and is an early indicator of how\n",
    "      accurate the model is during training.\n",
    "      A value of -1 causes the entire validation set to be used, which leads to\n",
    "      more stable results across training iterations, but may be slower on large\n",
    "      training sets.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--print_misclassified_test_images',\n",
    "      default=False,\n",
    "      help=\"\"\"\\\n",
    "      Whether to print out a list of all misclassified test images.\\\n",
    "      \"\"\",\n",
    "      action='store_true'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--model_dir',\n",
    "      type=str,\n",
    "      default='/tmp/imagenet',\n",
    "      help=\"\"\"\\\n",
    "      Path to classify_image_graph_def.pb,\n",
    "      imagenet_synset_to_human_label_map.txt, and\n",
    "      imagenet_2012_challenge_label_map_proto.pbtxt.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--bottleneck_dir',\n",
    "      type=str,\n",
    "      default='/tmp/bottleneck',\n",
    "      help='Path to cache bottleneck layer values as files.'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--final_tensor_name',\n",
    "      type=str,\n",
    "      default='final_result',\n",
    "      help=\"\"\"\\\n",
    "      The name of the output classification layer in the retrained graph.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--flip_left_right',\n",
    "      default=False,\n",
    "      help=\"\"\"\\\n",
    "      Whether to randomly flip half of the training images horizontally.\\\n",
    "      \"\"\",\n",
    "      action='store_true'\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--random_crop',\n",
    "      type=int,\n",
    "      default=0,\n",
    "      help=\"\"\"\\\n",
    "      A percentage determining how much of a margin to randomly crop off the\n",
    "      training images.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--random_scale',\n",
    "      type=int,\n",
    "      default=0,\n",
    "      help=\"\"\"\\\n",
    "      A percentage determining how much to randomly scale up the size of the\n",
    "      training images by.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  parser.add_argument(\n",
    "      '--random_brightness',\n",
    "      type=int,\n",
    "      default=0,\n",
    "      help=\"\"\"\\\n",
    "      A percentage determining how much to randomly multiply the training image\n",
    "      input pixels up or down by.\\\n",
    "      \"\"\"\n",
    "  )\n",
    "  FLAGS, unparsed = parser.parse_known_args()\n",
    "  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#our program\n",
    "#store your \n",
    "import tensorflow as tf, sys\n",
    "#import Image\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.image as mpimg\n",
    "img=mpimg.imread('haritest.jpg')\n",
    "imgplot = plt.imshow(img)\n",
    "plt.show()\n",
    "\n",
    "# change this as you see fit\n",
    "#image_path = sys.argv[1]\n",
    "\n",
    "# Read in the image_data\n",
    "#imgplot = plt.imshow('jackettest.jpg')\n",
    "plt.show()\n",
    "image_data = tf.gfile.FastGFile('haritest.jpg', 'rb').read()\n",
    "\n",
    "\n",
    "# Loads label file, strips off carriage return\n",
    "label_lines = [line.rstrip() for line \n",
    "                   in tf.gfile.GFile(\"new_labels.txt\")]\n",
    "\n",
    "# Unpersists graph from file\n",
    "with tf.gfile.FastGFile(\"new_graph.pb\", 'rb') as f:\n",
    "    graph_def = tf.GraphDef()\n",
    "    graph_def.ParseFromString(f.read())\n",
    "    _ = tf.import_graph_def(graph_def, name='')\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    # Feed the image_data as input to the graph and get first prediction\n",
    "    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')\n",
    "    \n",
    "    predictions = sess.run(softmax_tensor, \\\n",
    "             {'DecodeJpeg/contents:0': image_data})\n",
    "    \n",
    "    # Sort to show labels of first prediction in order of confidence\n",
    "    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]\n",
    "    \n",
    "    for node_id in top_k:\n",
    "        human_string = label_lines[node_id]\n",
    "        score = predictions[0][node_id]\n",
    "        print('%s (score = %.5f)' % (human_string, score))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3.0
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}